﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Xml.Serialization;
using NTTDATA.BEENChina.ResultCertification.Checker.Address;
using NTTDATA.BEENChina.ResultCertification.Checker.Text;
using NTTDATA.BEENChina.ResultCertification.Result;

using NTTDATA.BEENChina.ResultCertification.Checker.Date;
using NTTDATA.BEENChina.ResultCertification.Checker.Select;
using NTTDATA.BEENChina.ResultCertification.Checker.Name;
using NTTDATA.BEENChina.ResultCertification.Checker.Numeric;
using NTTDATA.BEENChina.ResultCertification.Checker.Tele; 

namespace NTTDATA.BEENChina.ResultCertification.Checker
{
    [Serializable]
    [XmlRoot(ElementName = "Verfity", IsNullable = true)]

    [XmlInclude(typeof(VerfityOneResult))]

    #region 日期检查子类
    
    [XmlInclude(typeof(VerfityRq0000))]

    [XmlInclude(typeof(VerfityRq0101))]
    [XmlInclude(typeof(VerfityRq0102))]

    [XmlInclude(typeof(VerfityRq0201))]
    [XmlInclude(typeof(VerfityRq0202))]

    //0203 年栏记载 以内 以外检出 默认以外
    [XmlInclude(typeof(VerfityRq0203))]
    [XmlInclude(typeof(VerfityRq0204))]
    [XmlInclude(typeof(VerfityRq0205))]

    [XmlInclude(typeof(VerfityRq0207))]
    [XmlInclude(typeof(VerfityRq0210))]
    [XmlInclude(typeof(VerfityRq0211))]
    [XmlInclude(typeof(VerfityRq0212))]
    [XmlInclude(typeof(VerfityRq0213))]
    [XmlInclude(typeof(VerfityRq0214))]
    [XmlInclude(typeof(VerfityRq0215))]
    [XmlInclude(typeof(VerfityRq0216))]
    //0217 0218  同 0212
    // 0218 -> 0212_31
    [XmlInclude(typeof(VerfityRq0219))]
    // 220 同 0212
    [XmlInclude(typeof(VerfityRq0221))]
    [XmlInclude(typeof(VerfityRq0222))]
    //0223 同 0222
    [XmlInclude(typeof(VerfityRq0224))]
    [XmlInclude(typeof(VerfityRq0225))]
    [XmlInclude(typeof(VerfityRq0226))]
    [XmlInclude(typeof(VerfityRq0227))]
    //0228 同 0227

    //229的条件和原有已经有出入
    [XmlInclude(typeof(VerfityRq0229))]
    [XmlInclude(typeof(VerfityRq0230))]
    [XmlInclude(typeof(VerfityRq0230))]

    [XmlInclude(typeof(VerfityRq0301))]
    
    //年栏记载规律 以内 检出
    //0232 同0203

    //日期录入各子项目检证
    [XmlInclude(typeof(VerfityRq0231))]
    //0231 - 0231_1
    //年号为空且年月日有记载时抽出

    //0234 - 0231_2
    //文字栏有记载年月日栏没有记载时抽出

    //整个录入结果有年月记载且第一行日期为空时抽出
    [XmlInclude(typeof(VerfityRq0235))]

    [XmlInclude(typeof(VerfityRq0301))]

    [XmlInclude(typeof(VerfityRq0302))]

    [XmlInclude(typeof(VerfityRq0303))]

    [XmlInclude(typeof(VerfityRq0304))]


    //公式检证
    [XmlInclude(typeof(VerfityRq0400))]

    [XmlInclude(typeof(VerfityRq0401))]

    #endregion

    #region 数值检查类

    //数值全部检出
    [XmlInclude(typeof(VerfityD0000))]
    //记载率_未(有)记载
    [XmlInclude(typeof(VerfityD0001))]
    //位数检证
    [XmlInclude(typeof(VerfityD0002))]
    //逻辑检证
    [XmlInclude(typeof(VerfityD0003))]
    //公式验证
    [XmlInclude(typeof(VerfityD0004))]
    

    
    //日期大于31或等于0时抽出
    [XmlInclude(typeof(VerfityD0005))]
    //通院日期是一个问号时抽出
    [XmlInclude(typeof(VerfityD0006))]
    //文字记载栏是一个问号时抽出检证
    [XmlInclude(typeof(VerfityD0007))]


    //第N行N列数值项目无记载，其余行列有数值项目记载
    [XmlInclude(typeof(VerfityD0008))]

    //连续的N组数值间有空内容时抽出
    [XmlInclude(typeof(VerfityD0009))]

    //第N行N列有/无记载
    [XmlInclude(typeof(VerfityD0010))]

    
    //第N行通院治疗日有/无记载
    [XmlInclude(typeof(VerfityD0100))]
    //连续的N组通院治疗日中间出现空行时抽出
    [XmlInclude(typeof(VerfityD0101))]
    //N组日期合并到一起是递增的一组数时抽出检证
    [XmlInclude(typeof(VerfityD0102))]
    //email地址检验
    [XmlInclude(typeof(VerfityD0200))]
    [XmlInclude(typeof(VerfityD0301))]
    [XmlInclude(typeof(VerfityD0302))]
    [XmlInclude(typeof(VerfityD0303))]
    [XmlInclude(typeof(VerfityD0400))]
    [XmlInclude(typeof(VerfityD0401))]

       
    #endregion

    #region 电话检查类

    [XmlInclude(typeof(VerfityT0000))]
    [XmlInclude(typeof(VerfityT0101))]
    [XmlInclude(typeof(VerfityT0301))]
    [XmlInclude(typeof(VerfityT0302))]
    [XmlInclude(typeof(VerfityT0303))]

    #endregion
    
    #region 选择项目检查类
    
    [XmlInclude(typeof(VerfityS0000))]
    [XmlInclude(typeof(VerfityS0001))]
    [XmlInclude(typeof(VerfityS0002))]
    [XmlInclude(typeof(VerfityS0003))]
    [XmlInclude(typeof(VerfityS0100))]

    [XmlInclude(typeof(VerfityS0200))]
    [XmlInclude(typeof(VerfityS0201))]
    [XmlInclude(typeof(VerfityS0202))]
    [XmlInclude(typeof(VerfityS0203))]

    [XmlInclude(typeof(VerfityS0301))]
    [XmlInclude(typeof(VerfityS0302))]
    [XmlInclude(typeof(VerfityS0303))]
    [XmlInclude(typeof(VerfityS0304))]
    [XmlInclude(typeof(VerfityS0400))]

    #endregion

    #region 姓名项目检查类

    [XmlInclude(typeof(VerfityN0000))]
    [XmlInclude(typeof(VerfityN0001))]
    [XmlInclude(typeof(VerfityN0002))]
    [XmlInclude(typeof(VerfityN0100))]

    [XmlInclude(typeof(VerfityN0201))]
    [XmlInclude(typeof(VerfityN0202))]
    [XmlInclude(typeof(VerfityN0301))]
    [XmlInclude(typeof(VerfityN0302))]
    [XmlInclude(typeof(VerfityN0303))]
    [XmlInclude(typeof(VerfityN0400))]

    [XmlInclude(typeof(VerfityN0101))]
    #endregion

    #region 住所检查类

    [XmlInclude(typeof(VerfityA0000))]
    [XmlInclude(typeof(VerfityA0001))]
    [XmlInclude(typeof(VerfityA0002))]
    [XmlInclude(typeof(VerfityA0003))]
    [XmlInclude(typeof(VerfityA0004))]
    [XmlInclude(typeof(VerfityA0005))]
    [XmlInclude(typeof(VerfityA0006))]
    [XmlInclude(typeof(VerfityA0007))]
    [XmlInclude(typeof(VerfityA0008))]
    [XmlInclude(typeof(VerfityA0009))]
    [XmlInclude(typeof(VerfityA0301))]
    [XmlInclude(typeof(VerfityA0302))]
    [XmlInclude(typeof(VerfityA0303))]

    #endregion

    #region 文字列检查类

    [XmlInclude(typeof(VerfityTx0000))]
    [XmlInclude(typeof(VerfityTx0100))]
    [XmlInclude(typeof(VerfityTx0201))]

    [XmlInclude(typeof(VerfityTx0301))]
    [XmlInclude(typeof(VerfityTx0302))]

    [XmlInclude(typeof(VerfityTx0400))]
    [XmlInclude(typeof(VerfityTx0401))]
    [XmlInclude(typeof(VerfityTx0406))]
    [XmlInclude(typeof(VerfityTx0410))]
    [XmlInclude(typeof(VerfityTx0411))]
    [XmlInclude(typeof(VerfityTx0412))]
    [XmlInclude(typeof(VerfityTx0404))]

    #endregion

    public  class Verfity
    {
        // Language.
        // [XmlAttribute("lang", Namespace = "http://www.w3.org/XML/1998/namespace")]       // OK
        [XmlAttribute("xml:lang")]                                                          // OK.
        public string Lang = "en";

        // Whitespace.
        // Set this to 'default' or 'preserve'.
        // [XmlAttribute("space", Namespace = "http://www.w3.org/XML/1998/namespace")]      // OK
        [XmlAttribute("xml:space")]                                                         // OK
        public string Space = "preserve"; 


        [Category("对象唯一标记"), Description("设置验证类唯一标记")]
        [ReadOnly(false)]
        public string Id { get; set; }

        [Category("对象名称"), Description("设置验证类名称")]
        public string Name { get; set; }


        [Category("验证类描述"), Description("设置验证类描述说明")]
        public string Memo { get; set; }


        protected ChildImage ChildImageObject;
   
        public void SetChildImage(ChildImage image)
        {
            this.ChildImageObject = image;
        }

        //public Verfity(ChildImage childImage)
        //{
        //    this.ChildImage = childImage;
        //}

        /// <summary>
        /// 验证字数
        /// </summary>
        [Browsable(false)]
        [XmlIgnore]
        public int VerfityWordCount { get; set; }

        [Browsable(false),XmlIgnore]
        public VerfityProperties Reason {get;set;}

        /// <summary>
        /// 无参数构造函数
        /// 供实例初始化时使用
        /// </summary>
        public Verfity(){}

        public virtual bool Check()
        {
            return true;
        }
        

        public static string GetSerialize(Verfity verfity)
        {
            return new Util.Serializer().SerializeXml(typeof(Verfity), verfity); 
        }

        public static Verfity SetPropertyReadOnly(Verfity obj, string propertyName, bool readOnly)
        {
            Type type = typeof(ReadOnlyAttribute);
            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj);
            AttributeCollection attrs = props[propertyName].Attributes;
            FieldInfo fld = type.GetField("isReadOnly", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance);
            if (fld != null)
            {
                fld.SetValue(attrs[type], readOnly);
            }

            return obj;
        }


        #region 验证相关方法
        

        /// <summary>
        /// 受番号上的日期
        /// </summary>
        /// <returns></returns>
        protected DateTime? GetOrderDate()
        {
            if (ChildImageObject != null)
            {
                if (ChildImageObject.OrderId != null)
                {
                    string[] arrayOrder = ChildImageObject.OrderId.Split(new char[] { '-' });
                    string dateFormat = "yyyyMMdd-HHmmss";

                    string orderDate = string.Format("{2}-{3}", arrayOrder);

                    CultureInfo ci = new CultureInfo("en-US");
                    Calendar cal = new GregorianCalendar();
                    ci.DateTimeFormat.Calendar = cal;
                    return DateTime.ParseExact(orderDate, dateFormat, ci);
                }
            }
            return null;
        }

        /// <summary>
        /// 结果为空的行数
        /// </summary>
        /// <param name="rowResult"></param>
        /// <returns></returns>
        protected int EmptyColumnCount(IEnumerable<string> rowResult)
        {
            if (rowResult != null)
            {
                int emptyColumn = rowResult.Sum(t => EmptyResultCount(t));

                
                    return emptyColumn;
            }

            return 0;
        }

        /// <summary>
        /// 录入结果是是否为空白
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        protected static int EmptyResultCount(string result)
        {
            if (String.IsNullOrEmpty(result.Replace("/", string.Empty)))
            {
                return 1;
            }
            return 0;
        }

        /// <summary>
        /// 结果中包含问号的行数
        /// </summary>
        /// <param name="rowResult"></param>
        /// <returns></returns>
        protected int QuestionMarkColumnCount(IEnumerable<string> rowResult)
        {
            if (rowResult != null)
            {
                int questionColumn = rowResult.Sum(t =>QuestionMarkResultCount(t));
                
                return questionColumn;
            }

            return 0;
        }

        /// <summary>
        /// 结果中包含问号的行数
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        protected static int QuestionMarkResultCount(string result)
        {
            if ( result.Replace("/", string.Empty).Contains("?") )
            {
                return 1;
            }
            return 0;
        }


        #endregion

    }


}
